﻿#pragma once

#include "rockhopper.h"
using namespace Platform;

namespace XiaoWeiOffLineSDK
{

	public enum class OffLine_RockhopperDataType
	{
		ROCKHOPPER_DATA_TYPE_SAMPLE_INT_16,
		ROCKHOPPER_DATA_TYPE_FEATURE_INT_16
	};
	public ref struct Fields sealed
	{
	public:
		void setSpeech(unsigned int val)
		{
			speech = val;
		}
		unsigned int getSpeech()
		{
			return speech;
		}
		void setFrontend(unsigned int val)
		{
			frontend = val;
		}
		unsigned int getFrontend()
		{
			return frontend;
		}
		void setScorer(unsigned int val)
		{
			scorer = val;
		}
		unsigned int getScorer()
		{
			return scorer;
		}
		void setDecoder(unsigned int val)
		{
			decoder = val;
		}
		unsigned int getDecoder()
		{
			return decoder;
		}

		void setReserved(unsigned int val)
		{
			reserved = val;
		}
		unsigned int getReserved()
		{
			return reserved;
		}

		/*	Fields& operator=(const Fields& f)
			{
				return
			}*/

	private:
		unsigned int speech;
		unsigned int frontend;
		unsigned int scorer;
		unsigned int decoder;
		unsigned int reserved;
	};

	public ref struct Offline_AsrEngineStatistics sealed
	{

	public:
		void setValue(int val)
		{
			value = val;
		}
		int getValue()
		{
			return value;
		}
		void setFrontend(unsigned int val)
		{
			frontend = val;
		}
		unsigned int getFrontend()
		{
			return frontend;
		}
		void setSignalvl(int val)
		{
			signalvl = val;
		}
		int getSigalvl()
		{
			return signalvl;
		}
		void setSamples_captured_ms(int val)
		{
			samples_captured_ms = val;
		}
		int gettSamples_captured_ms()
		{
			return samples_captured_ms;
		}
		void setFrames_extracted_ms(int val)
		{
			frames_extracted_ms = val;
		}
		int getFrames_extracted_ms()
		{
			return frames_extracted_ms;
		}
		void setFrames_decoded_ms(int val)
		{
			frames_decoded_ms = val;
		}
		int getFrames_decoded_ms()
		{
			return frames_decoded_ms;
		}

		void setUttRtFactor(float val)
		{
			uttRtFactor = val;
		}
		float getUttRtFactor()
		{
			return uttRtFactor;
		}
		void setUtt_min_snr(int val)
		{
			utt_min_snr = val;
		}
		int getUtt_min_snr()
		{
			return utt_min_snr;
		}
		void setUtt_max_snr(int val)
		{
			utt_max_snr = val;
		}
		int getUtt_max_snr()
		{
			return utt_max_snr;
		}
		void setUtt_snr(int val)
		{
			utt_snr = val;
		}
		int getUtt_snr()
		{
			return utt_snr;
		}

	private:
		int value;
		unsigned int frontend;
		int signalvl;
		int samples_captured_ms;
		int frames_extracted_ms;
		int frames_decoded_ms;
		float uttRtFactor;
		int utt_min_snr;
		int utt_max_snr;
		int utt_snr;

	};
	public delegate int delegateUtteranceCallback(Object^ obj, const Array<byte>^ samples, int nSamples, String^ UtteranceId, String^ UtteranceText, float score, int isFinal);
	public delegate void delegateStatisticsOfAsrEngine(Offline_AsrEngineStatistics^ engine);
	public delegate void delegateEventCallback(int eventCode, int value);
	public ref class OffLineSDK sealed
	{
	private:
		ASR_HANDLE asrengine = 0;
		WFST_HANDLE wfst = 0;
		~OffLineSDK();
	public:
		OffLineSDK();
	public:
		int  OffLine_RockhopperFSInitialize(Platform::String^ configurationFilename, Platform::String^ resourceDirectory, Platform::String^ userResourceDirectory);
		int  OffLine_RockhopperFSUpdateDynResource(Platform::String^ configurationFilename, Platform::String^ resourceDirectory, Platform::String^ userResourceDirectory, int tagId);
		int  OffLine_RockhopperFSSetResultCallback();
		int  OffLine_RockhopperFSStartEngine();
		int  OffLine_RockhopperFSStopEngine();
		int  OffLine_RockhopperFSReleaseEngine();
		int  OffLine_RockhopperFSGetStatistics();
		int  OffLine_RockhopperFSPushSamples(const Array<int16>^ samples, int nSamples);
		int  OffLine_RockhopperFSConvertJSGFToFST(Platform::String^ configurationFilename, Platform::String^ grammar, Platform::String^ grammarRule, int grammarSize, int grammarRuleSize, int firstWordID);
		int  OffLine_RockhopperFSConvertARPAToFST(Platform::String^ configurationFilename, const Array<byte>^ arpa, int arpaSize, int firstWordID);
		int  OffLine_RockhopperFSConvertPhrasesToFST(Platform::String^ configurationFilename, const Array<byte>^ phrases, int phrasesSize, int firstWordID);
		int  OffLine_RockhopperFSConvertFST(Platform::String^ configurationFilename, const Array<byte>^ wfst_text, int text_size, int firstWordID);
		int  OffLine_RockhopperFSReleaseFST();
		int OffLine_RockhopperFSSetEventCallback();
		int  OffLine_RockhopperFSPushData(const Array<byte>^ wfst_text, int elementCount, OffLine_RockhopperDataType type);
		static event delegateUtteranceCallback^ EventUtteranceCallback;
		static event delegateStatisticsOfAsrEngine^ EventGeteStatisticsOfAsrEngine;
		static event delegateEventCallback^ FSSetEventCallback;
	private:
		static long OffLine_UtteranceCallback(void* p, const short* samples, int nSamples, const char* UtteranceId, const char* UtteranceText, float score, int isFinal);
		static void  OffLine_FSSetEventCallback(void* p, int eventCode, int value);
	};
}
